@script RequireComponent(BoxCollider)
@script RequireComponent(Transform)

// RequireComponent son las propiedades que necesita el objeto donde se le agrega el script

// Controls axis points x-left, y-screen, z-down

// ~CLASS(ES) *****************************************************************

class MovementBoundaries {
	var initial:Vector3 = Vector3.zero;
	var last:Vector3 = Vector3.zero;
	var limit:float = 80;
	
	function Reset() {
		this.initial = Vector3.zero;
		this.last = Vector3.zero;
	}
	
	function IsNull() {
		return initial == Vector3.zero && last == Vector3.zero;
	}
}


// ~VARIABLE(S) TO SET ********************************************************
public  var guiCamera   : Camera;

private var layer       : int;
private var boxCollider : BoxCollider;
private var boundaries  : MovementBoundaries = MovementBoundaries();
private var moving      : boolean;

private var debug:boolean;

// ~CALLED FUNCTION(S) ********************************************************
function Start() {
	layer = 1 << 8; // This is the GUI layer shift index
	boxCollider = GetComponent(BoxCollider);
	debug = false;
	moving = false;
	// The initial placement is (0,0) in local coordinates
}

// The final idea is to ray trace the object. It must have a collider. <- It worked
// Another idea: use rectangle to now when a point is inside. 
// Idea: Use GuiTexture over camera
function Update() {
	var count = Input.touchCount;
	
	if (count == 0) {
		if (!boundaries.IsNull()) Reset();
		return;
	}
	
	// As there are several controls, one has to consider multi-touch on the screen
	var objectWasHit:boolean = false;
	for (var i:int = 0; i < count && !objectWasHit; i++) {
		var touch: Touch = Input.GetTouch(i);
		if (ObjectHit(touch) || moving) {
			objectWasHit = true;
			if (touch.phase == TouchPhase.Began) {
				boundaries.initial = touch.position;
				moving = true;
			}
			var destination:Vector3 = touch.position - boundaries.initial;
			if(Mathf.Abs(destination.x) < boundaries.limit) boundaries.last.x = destination.x;
			if(Mathf.Abs(destination.y) < boundaries.limit) boundaries.last.y = destination.y;
			transform.localPosition.x = -boundaries.last.x;
			transform.localPosition.z = -boundaries.last.y;
			
		}
		else if (!boundaries.IsNull()) Reset();
	}
	
}

function Reset() {
	boundaries.Reset();
	//transform.localPosition = Vector3.zero;
	if (moving) iTween.MoveTo(this.gameObject, {"position":Vector3.zero, "time":0.5, "islocal":true});
	moving = false;
}

// ~FUNCTION(S) *****************************************************************
// Ray cast to our gui object
// Gui layers are index by bitshifting an integer the desired "index"
function ObjectHit(touch: Touch) {
	var ray:Ray = guiCamera.ScreenPointToRay(touch.position);
	DM("Touch(" + touch.position.x + ", " + touch.position.y + ") - Ray(" + ray.origin.x + ", " + ray.origin.y + ")");
	
	var hit:RaycastHit;
    var tapped:boolean = Physics.Raycast(ray, hit, Mathf.Infinity, layer);
	if (tapped && debug) Debug.DrawLine(ray.origin, hit.point);
	return tapped;
}

// Debugging
function DM(message:String) {
	if (debug) Debug.Log("Joystick.js: " + message);
}